/**
 * @author Dendi
 * @date 2016/6/14
 */


//-----------------------------------------------------------
//                      jquery api
//-----------------------------------------------------------
$.extend($.fn,
    {
        /**
         * 高级查询form 查询参数收集  $('#search-form').searchFormDataCollect()
         * @returns [{op:'',field:'',value:''}]
         */
        searchFormDataCollect() {

            return this.map(function () {
                return this.elements ? jQuery.makeArray(this.elements) : this;
            })
                .filter(function () {
                    return this.name && !this.disabled &&
                        (this.checked || /select|textarea/i.test(this.nodeName) ||
                        /text|hidden|password|search/i.test(this.type));
                })
                .map(function (i, elem) {
                    var val = jQuery(this).val();
                    var data = jQuery(this).data();
                    return val == null ? null :
                        jQuery.isArray(val) ?
                            jQuery.map(val, function (val, i) {
                                return {
                                    field: elem.name, value: val,
                                    op: $.isEmptyObject(data["op"]) ? null : data["op"]
                                };
                            }) :
                        {
                            field: elem.name, value: val,
                            op: $.isEmptyObject(data["op"]) ? null : data["op"],
                        };
                }).get();
        },
        /**
         * jquery控件重置操作清空操作
         * 调用方式:    $(el).reset()
         */
        reset() {
            var tag = jQuery(this)[0].tagName;
            switch (tag) {
                // <form>
                case "FORM":
                    jQuery(this)[0].reset();
                    break;
                // <input> <select/>
                case "INPUT":
                    jQuery(this).val("");
                    break;
                case "SELECT":
                    jQuery(this).val("");
                    break;
                // <a> <span> <p> <div>
                default:
                    jQuery(this).html("");
            }
        },
        initSelect(){
            $.each(this, function (i, _each) {
                var $select = $(_each);
                var _type = $select.data("enum-key");
                if (archer.utils.isEmpty(_type)) return;
                $select.html(archer.enum.selectWrapper(_type, $select.data("enum-all"), $select.data("enum-default")));

            });
        }
    }
);

//-----------------------------------------------------------
//      对外提供 archer.utils archer.toast archer.http
//      archer.confirm  archer.enum
//-----------------------------------------------------------

window.archer = window.archer || {};


//-----------------------------------------------------------
//      archer.utils
//-----------------------------------------------------------
archer.utils = (function () {

    var _isEmpty = function (obj) {
        return $.isEmptyObject(obj);
    };
    var _jsonConverter = function (obj) {
        if (typeof obj === 'string') {
            return JSON && JSON.parse(obj);
        }
        if (typeof obj === 'object') {
            return JSON && JSON.stringify(obj);
        }

    };
    //  移除数组list对象的obj,满足obj[key]为空
    var _removeListObj = function (list, key) {
        var arr = list || [];
        key = key || "value";
        _.remove(list, function (item) {
            return _.isEmpty(item[key]);
        });
        return arr;
    };

    var _basicCondition = function (index, size, query, orders) {
        return {
            pageIndex: index || 1,
            pageSize: size || 10,
            queryItems: query,
            orderByItems: orders
        };
    };

    var _genQueryCondition = function (params, el) {
        var orders = [];
        if (!_isEmpty(params.data.sortName)) {
            orders = [{
                "direction": params.data.sortOrder, "field": params.data.sortName
            }];
        }
        return _jsonConverter(_basicCondition(params.data.pageNumber, params.data.pageSize,
            _removeListObj(el.searchFormDataCollect()), orders));
    };

    // 初始化日期范围控件
    var _initDateRange = function initDateRange(el, startFormat, endFormat) {

        var _startFormat = startFormat || 'YYYY-MM-DD 00:00:00';
        var _endFormat = endFormat || 'YYYY-MM-DD 23:59:59';
        $(el).daterangepicker(
            {
                ranges: {
                    '今天': [moment(), moment()],
                    '昨天': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
                    '最近7天': [moment().subtract(6, 'days'), moment()],
                    '最近30天': [moment().subtract(29, 'days'), moment()],
                    '本月': [moment().startOf('month'), moment().endOf('month')],
                    '上个月': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')]
                },

                format: 'YYYY-MM-DD',
                separator: " 至 ",

                locale: {
                    "applyLabel": "确认",
                    "cancelLabel": "清除",
                    "fromLabel": "从",
                    "toLabel": "到",
                    "customRangeLabel": "自定义区间",
                    "weekLabel": "W",
                    "daysOfWeek": [
                        "天",
                        "一",
                        "二",
                        "三",
                        "四",
                        "五",
                        "六"
                    ],
                    "monthNames": [
                        "一月",
                        "二月",
                        "三月",
                        "四月",
                        "五月",
                        "六月",
                        "七月",
                        "八月",
                        "九月",
                        "十月",
                        "十一月",
                        "十二月"
                    ],
                    "firstDay": 1
                },
                startDate: moment().startOf('month'),
                endDate: moment().endOf('month')
            },
            function (start, end) {
                $(el + "Start").val(start.format(_startFormat));
                $(el + "End").val(end.format(_endFormat));
            }
        );

        $(el).on('cancel.daterangepicker', function (ev, picker) {
            var that = this;
            $(that).val('');
            $(el + "Start").val('');
            $(el + "End").val('');
        });
    };

    return {
        isEmpty(obj){
            return _isEmpty(obj);
        },
        isNotEmpty(obj){
            return !_isEmpty(obj);
        },
        strToJson(str) {
            return _jsonConverter(str);
        },
        jsonToStr(json) {
            return _jsonConverter(json);
        },
        isString (str) {
            return ((str instanceof String) || (typeof str).toLowerCase() == 'string');
        },
        isSuccess(result) {
            if (_isEmpty(result)) {
                return false;
            }
            return result.resultCode == "SUCCESS";
        },
        removeNullObj(arr, key){
            return _removeListObj(arr, key);
        },
        mergeParams(params, $el){
            return _genQueryCondition(params, $el);
        },
        initDateRange(el, startFormat, endFormat){
            return _initDateRange(el, startFormat, endFormat);
        }
    };
})();

//-----------------------------------------------------------
//      archer.http
//-----------------------------------------------------------
/**
 *
 * @type {{post, get, body, getCtx, getParamObj, form, getUrlPrefix}}
 */
archer.http = (function () {

    var server_url = window.location.origin;
    //默认携带的参数
    var requestObj = function (url) {
        return {
            url: server_url + url,
            type: 'post',
            dataType: 'json',
            returnAll: false,
            data: {}
        };
    };

    /**
     * 移除值为null的属性
     * @param obj
     * @returns
     */
    var removeNullProps = function (obj) {
        obj = obj || {};

        var key;
        for (key in obj) {
            if (obj[key] === null) {
                delete obj[key];
            }
        }
        return obj;
    };

    var httpSend = function (url, data, sucessCallBack, errCallBack, method) {
        var request = requestObj(url);
        var httpMethod = method || 'post';

        if (httpMethod == 'get') {
            request.type = httpMethod;
        }

        if (httpMethod == 'post' || httpMethod == 'get') {
            request.data = removeNullProps(data);
        }

        if (httpMethod == 'body') {
            request.data.body = archer.jsonToStr(removeNullProps(data));
            request.headers = {'content-type': 'application/json'};
        }

        if (sucessCallBack) {
            request.success = function (ret) {
                if (ret) {
                    if (ret.resultCode && ret.resultCode == "NOT_LOGINED") {
                        archer.toast.warning({msg: $Constants.messages.notLogin});
                        setTimeout(
                            //跳转到登录页面
                            function () {
                                location.href = window.location.origin + "/logout";
                            },
                            3000
                        );
                        return;
                    }

                    if (sucessCallBack) {
                        sucessCallBack(ret);
                    }
                } else {
                    if (errCallBack) {
                        errCallBack(ret);
                        return;
                    }
                }
            };
        }
        request.error = function (err) {
            console.log("err info:", err);
            if (!archer.utils.isEmpty(err)) {
                if (err.status == '500') {
                    archer.toast.error(
                        {
                            msg: $Constants.messages.serverInternalError,
                            hideAfter: 10
                        }
                    );
                }
            }
            if (errCallBack) {
                errCallBack(err);
            }
        };
        $.ajax(request);
    };

    return {

        /**
         * post方法
         * @param url
         * @param data  post参数，json对象
         * @param sucessCallBack
         * @param errCallBack
         */
        post (url, data, sucessCallBack, errCallBack) {
            httpSend(url, data, sucessCallBack, errCallBack);
        },

        /**
         * get方法
         * @param url
         * @param data  get参数，和post统一用json对象，不要在url中手工拼接参数
         * @param sucessCallBack
         * @param errCallBack
         */
        get (url, data, sucessCallBack, errCallBack) {
            httpSend(url, data, sucessCallBack, errCallBack, 'get');
        },

        /**
         * 参数放在body中传递，后台要使用@requestBody接
         * @param url
         * @param data  json对象
         * @param sucessCallBack
         * @param errCallBack
         */
        body(url, data, sucessCallBack, errCallBack) {
            httpSend(url, data, sucessCallBack, errCallBack, 'body');
        },
        getCtx() {
            return window.location.origin;
        },
        getQueryString(name) {
            var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
            var r = window.location.search.substr(1).match(reg);
            return r != null ? unescape(r[2]) : "";
        }
    };

})();

//-----------------------------------------------------------
//      archer.toast
//-----------------------------------------------------------
/**
 *
 * @type {{success, info, error, warning}}
 */
archer.toast = (function () {
    var defaultOpts = {
        extraClasses: 'messenger-fixed messenger-on-bottom messenger-on-left',
        scrollTo: true,
        showCloseButton: true
    };

    var toast = function (msg, type, hideAfter, theme, id) {
        Messenger().post($.extend(
            defaultOpts,
            {
                message: msg,
                type: type,
                hideAfter: hideAfter,   // 单位秒(s)
                theme: theme,
                id: id
            }
        ));
    };
    var validate = function (rows, status, keyField, showSelections) {
        var msg = "";
        $.each(rows, function (i, row) {
            if (row[keyField] === status) {
                msg = row.id + "|" + msg;
            }
        });
        return showSelections ? msg : !!msg;
    };
    return {
        success({msg = $Constants.messages.toastSuccess, hideAfter = $Config.toast.hideAfter, theme = 'flat', id = "archer-success"}) {
            toast(msg, "success", hideAfter, theme, id);
        },
        info({msg = $Constants.messages.toastInfo, hideAfter = $Config.toast.hideAfter, theme = 'flat'}) {
            toast(msg, "info", hideAfter, theme);
        },
        error({msg = $Constants.messages.toastError, hideAfter = $Config.toast.hideAfter, theme = 'flat'}) {
            toast(msg, "error", hideAfter, theme);
        },
        warning({msg = $Constants.messages.toastInfo, hideAfter = $Config.toast.hideAfter, theme = 'flat'}) {
            toast(msg, "warning", hideAfter, theme);
        },
        invalidSelections({msg = $Constants.messages.toastWarning, keyField = "status", invalidStatus = "", rows = [], showSelections = false}){
            if (rows.length == 0) {
                toast($Constants.messages.selectRows, "warning");
                return true;
            }
            if (!!validate(rows, invalidStatus, keyField, showSelections)) {
                toast(msg, "warning");
                return true;
            }
            return false;
        }
    };

})();

//-----------------------------------------------------------
//      archer.confirm
//-----------------------------------------------------------
/**
 * 阻断式确认提示框
 * @param confirmCallback 确认按钮回调方法
 * @param cancelCallback 取消按钮回调方法
 * @param title 标题
 * @param content 内容
 * @param confirmBtnLabel 确认按钮文本，default '确认'
 */
archer.confirm = function (confirmCallback, cancelCallback, title, content, confirmBtnLabel) {
    var defaultOpts = {
        icon: 'fa fa-warning',
        theme: 'material',
        keyboardEnabled: true,
        confirmButtonClass: 'btn-success',
        cancelButton: '取消',
        backgroundDismiss: true,    // 鼠标点击外框关闭confirm
        closeIconClass: 'glyphicon glyphicon-remove',

    };
    if (confirmCallback) {
        defaultOpts.confirm = function () {
            confirmCallback();
            return true;
        };
    }
    if (cancelCallback) {
        defaultOpts.cancel = function () {
            cancelCallback();
            return true;
        };
    }

    return $.confirm($.extend(
        {
            title: title || '确认框',
            content: content || '是否确认操作?',
            confirmButton: confirmBtnLabel || '确认',

        },
        defaultOpts
    ));
};

//-----------------------------------------------------------
//          archer.enum
//-----------------------------------------------------------
archer.enum = (function () {
    var eData = $Enums;

    var convertData = function (comboData, _l, _v) {
        comboData = comboData || [];
        comboData.push({
            "id": _v,
            "text": _l
        });
    };
    var genOpts = function (_l, _v, defaultValue) {
        if (defaultValue == _v) {
            return "<option value='" + _v + "' selected>" + _l + "</option>";
        } else {
            return "<option value='" + _v + "'>" + _l + "</option>";
        }

    };
    // combo data {idField:"",labelField:"",selected:0}
    var comboWrapper = function (key, includeAll) {
        var comboData = [];
        var options = (key === undefined) ? eData : eData[key];
        // 是否显示全部
        includeAll = includeAll || (includeAll === undefined);
        if (includeAll) {
            convertData(comboData, "全部", "");
        }
        if (!archer.utils.isEmpty(options)) {
            for (key in options) {
                if (typeof options[key] === 'object') {
                    var obj = options[key];
                    for (_v in obj) {
                        convertData(comboData, obj[_v], _v);
                    }
                } else {
                    convertData(comboData, options[key], key);
                }

            }
        }

        return comboData;
    };
    // select options <option value="1">是</option>
    var convertSelectOptions = function (enumKey, includeAll, defaultValue) {
        var options = eData[enumKey];
        if (archer.utils.isEmpty(options)) return;
        var opts = "";
        // 是否显示全部
        if (includeAll) {
            opts = opts + genOpts("全部", "");
        }
        for (k in options) {
            opts = opts + genOpts(options[k], k, defaultValue);
        }
        return opts;
    };

    return {
        /**
         * 枚举数据转成下拉框数据
         * @param dataKey
         * @param showAll 是否显示<option value="">全部</option>
         */
        getComboData(type, showAll){
            return comboWrapper(type, showAll);
        },
        /**
         * 后台json数据转成下拉数据源
         * @param _data
         * @param _v    作为id的属性名
         * @param _l    作为text的属性名
         * @returns {Array}
         */
        convertJson(_data, _v, _l){
            var arr = [];
            if (_.isArray(_data)) {
                _.each(function (item) {
                    convertData(arr, item[_v], item[_l]);
                });
            } else {
                convertData(arr, _data[_v], _data[_l]);
            }
            return arr;
        },
        selectWrapper(_enumkey, showAll, defaultValue){
            return convertSelectOptions(_enumkey, showAll, defaultValue);
        }

    };
})();